package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"
)

var skip string

func main() {
	flag.StringVar(&skip, "skip", "", "-skip [panel|datasource].[pluginType]  e.g. -skip panel.demo,datasource.demo  , this will skip installing the panel plugin with type demo and also skips the datasource plugin with type demo")
	flag.Parse()

	skipList := strings.Split(skip, ",")
	skipMap := make(map[string]bool)
	for _, skip := range skipList {
		skipMap[skip] = true
	}

	cmd := exec.Command("bash", "-c", "mkdir -p ../frontend/src/views/dashboard/plugins/external/panel")
	cmd.CombinedOutput()

	cmd = exec.Command("bash", "-c", "mkdir -p ../frontend/src/views/dashboard/plugins/external/datasource")
	cmd.CombinedOutput()

	importPluginsStr1 := `
// DON'T modify this file, it is automatically generated by xobserve external plugin system
import { DatasourcePluginComponents, PanelPluginComponents } from "types/plugin"
`

	// import candlestickPanel from "./panel/candlestick"

	// import victoriaMetricsDatasrouceComponents from "./datasource/victoriaMetrics"

	// export const externalPanelPlugins: Record<string,PanelPluginComponents> = {
	// 	[candlestickPanel.settings.type]: candlestickPanel,

	// }
	// export const externalDatasourcePlugins: Record<string,DatasourcePluginComponents> = {
	// 	[victoriaMetricsDatasrouceComponents.settings.type]: victoriaMetricsDatasrouceComponents,
	// }
	panelExportStr := `
export const externalPanelPlugins: Record<string,PanelPluginComponents> = {`

	{
		builtInPanels, err := os.ReadDir("../frontend/src/views/dashboard/plugins/built-in/panel")
		if err != nil {
			log.Fatal("read panel dir error", err)
		}
		currentPanelsMap := make(map[string]bool)
		for _, panel := range builtInPanels {
			currentPanelsMap[panel.Name()] = true
		}

		// generate panel plugins
		panels, err := os.ReadDir("./panel")
		if err != nil {
			log.Fatal("read panel dir error", err)
		}

		panelPluginsList := make([]map[string]string, 0)

		for _, panel := range panels {
			panelType := panel.Name()
			n := strings.Join([]string{"panel", panelType}, ".")
			if skipMap[n] {
				log.Println("skip panel plugin: ", panelType)
				continue
			}

			if panelType == ".DS_Store" {
				continue
			}
			if _, ok := currentPanelsMap[panelType]; ok {
				log.Println("ERROR !! The same panel name already exists in built-in panels: <", panelType, ">, please rename the panel you want to add")
				continue
			}

			// cp panel codes into src/views/dashboard/plugins/panel
			cmdStr := fmt.Sprintf("cp -r ./panel/%s ../frontend/src/views/dashboard/plugins/external/panel", panelType)
			cmd = exec.Command("bash", "-c", cmdStr)
			if _, err := cmd.CombinedOutput(); err != nil {
				log.Println("copy plugin code dir  error: ", err, ", panel: ", panelType)
				continue
			}

			panelPluginsList = append(panelPluginsList, map[string]string{
				"type": panelType,
			})

			componentStr := panelType + "Panel"
			importPluginsStr1 += fmt.Sprintf("\nimport %s from \"./panel/%s\"", componentStr, panelType)

			panelExportStr += fmt.Sprintf("\n\t[%s.settings.type]: %s,", componentStr, componentStr)
		}

		panelExportStr += "\n}"
	}

	datasourceExportStr := `
export const externalDatasourcePlugins: Record<string,DatasourcePluginComponents> = {`

	{
		builtInDatasources, err := os.ReadDir("../frontend/src/views/dashboard/plugins/built-in/datasource")
		if err != nil {
			log.Fatal("read panel dir error", err)
		}
		currentDatasourceMap := make(map[string]bool)
		for _, ds := range builtInDatasources {
			currentDatasourceMap[ds.Name()] = true
		}

		// generate panel plugins
		datasources, err := os.ReadDir("./datasource")
		if err != nil {
			log.Fatal("read datasource dir error", err)
		}

		datasourcePluginsList := make([]map[string]string, 0)

		for _, ds := range datasources {
			dsType := ds.Name()

			n := strings.Join([]string{"datasource", dsType}, ".")
			if skipMap[n] {
				log.Println("skip datasource plugin: ", dsType)
				continue
			}

			if dsType == ".DS_Store" {
				continue
			}
			if _, ok := currentDatasourceMap[dsType]; ok {
				log.Println("ERROR !! The same datasource name already exists in built-in datasources: <", dsType, ">, please rename the datasource you want to add")
				continue
			}

			// cp panel codes into src/views/dashboard/plugins/panel
			cmdStr := fmt.Sprintf("cp -r ./datasource/%s ../frontend/src/views/dashboard/plugins/external/datasource", dsType)
			cmd = exec.Command("bash", "-c", cmdStr)
			if _, err := cmd.CombinedOutput(); err != nil {
				log.Println("copy plugin code dir  error: ", err, ", datasource: ", dsType)
				continue
			}

			datasourcePluginsList = append(datasourcePluginsList, map[string]string{
				"type": dsType,
			})

			componentStr := dsType + "Datasrouce"
			importPluginsStr1 += fmt.Sprintf("\nimport %s from \"./datasource/%s\"", componentStr, dsType)

			datasourceExportStr += fmt.Sprintf("\n\t[%s.settings.type]: %s,", componentStr, componentStr)
		}

		datasourceExportStr += "\n}"
	}

	externalPluginFile := importPluginsStr1 + panelExportStr + datasourceExportStr

	// generate externalPlugins.ts file
	err := os.WriteFile("../frontend/src/views/dashboard/plugins/external/plugins.ts", []byte(externalPluginFile), 0666)
	if err != nil {
		log.Fatal("write plugin.json error", err)
	}

	// install query plugins
	cmd = exec.Command("bash", "-c", "mkdir -p ../query/internal/plugins/external")
	cmd.CombinedOutput()

	queryPlugins, err := os.ReadDir("./query")
	if err != nil {
		log.Fatal("read query plugin dir error", err)
	}

	pluginFileStr := `package external

/* Auto generated by xobserve plugins building tools */
	
`

	for _, q := range queryPlugins {
		queryType := q.Name()
		n := strings.Join([]string{"query", queryType}, ".")
		if skipMap[n] {
			log.Println("skip query plugin: ", queryType)
			continue
		}

		if queryType == ".DS_Store" {
			continue
		}

		cmdStr := fmt.Sprintf("cp -r ./query/%s ../query/internal/plugins/external", queryType)
		cmd = exec.Command("bash", "-c", cmdStr)
		if _, err := cmd.CombinedOutput(); err != nil {
			log.Println("copy plugin code dir  error: ", err, ", query plugin: ", queryType)
			continue
		}

		pluginFileStr += fmt.Sprintf("\nimport _ \"github.com/xObserve/xObserve/query/internal/plugins/external/%s\"", queryType)
	}

	// generate plugins.go file
	err = os.WriteFile("../query/internal/plugins/external/plugins.go", []byte(pluginFileStr), 0666)
	if err != nil {
		log.Fatal("write plugins.go error", err)
	}

	log.Println("Generate panel plugins file successfully!")
}
